#!/bin/bash

# CDN 上传脚本
# 支持腾讯云OSS、阿里云OSS等多种CDN服务

set -e

# 配置
CDN_TYPE=""  # tencent 或 aliyun
TENCENT_SECRET_ID=""
TENCENT_SECRET_KEY=""
TENCENT_BUCKET=""
TENCENT_REGION=""
ALIYUN_ACCESS_KEY_ID=""
ALIYUN_ACCESS_KEY_SECRET=""
ALIYUN_BUCKET=""
ALIYUN_REGION=""
SOURCE_DIR="./claude-mirror"

# 加载 .env 文件（如果存在）
if [ -f ".env" ]; then
    echo "加载 .env 文件..."
    set -a
    source .env
    set +a
fi

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --tencent)
            CDN_TYPE="tencent"
            shift
            ;;
        --aliyun)
            CDN_TYPE="aliyun"
            shift
            ;;
        --source-dir)
            SOURCE_DIR="$2"
            shift 2
            ;;
        --help)
            echo "用法: $0 [选项]"
            echo ""
            echo "选项:"
            echo "      --tencent               使用腾讯云OSS"
            echo "      --aliyun                使用阿里云OSS"
            echo "      --source-dir DIR        源目录 (默认: ./claude-mirror)"
            echo "      --help                  显示此帮助信息"
            echo ""
            echo "环境变量:"
            echo "  腾讯云:"
            echo "    TENCENT_SECRET_ID         腾讯云 Secret ID"
            echo "    TENCENT_SECRET_KEY        腾讯云 Secret Key"
            echo "    TENCENT_BUCKET            OSS存储桶名称"
            echo "    TENCENT_REGION            区域 (如: ap-beijing)"
            echo ""
            echo "  阿里云:"
            echo "    ALIYUN_ACCESS_KEY_ID      阿里云 Access Key ID"
            echo "    ALIYUN_ACCESS_KEY_SECRET 阿里云 Access Key Secret"
            echo "    ALIYUN_BUCKET             OSS存储桶名称"
            echo "    ALIYUN_REGION             区域 (如: cn-beijing)"
            exit 0
            ;;
        *)
            echo "未知参数: $1"
            echo "使用 --help 查看帮助"
            exit 1
            ;;
    esac
done

# 检查依赖
check_dependency() {
    local cmd="$1"
    local name="$2"

    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "错误: 需要安装 $name" >&2
        exit 1
    fi
}

check_dependency "curl" "curl"
check_dependency "jq" "jq"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 腾讯云COS上传函数
upload_to_tencent_oss() {
    local file_path="$1"
    local remote_path="$2"

    # 构建请求
    local method="PUT"
    local host="${TENCENT_BUCKET}.cos.${TENCENT_REGION}.myqcloud.com"
    local uri="/$remote_path"
    local content_type="application/octet-stream"

    # 时间戳
    local start_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    local end_time=$(date -u -d "+1 day" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u -v+1d +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null)
    local key_time="$start_time;$end_time"

    # 签名时间
    local sign_time="$start_time;$end_time"

    # 构建签名头部
    local header_list="content-type;host"
    local header_list_lowercase=$(echo "$header_list" | tr '[:upper:]' '[:lower:]')

    # 构建签名参数
    local url_param_list=""
    local url_param_list_lowercase=""

    # 计算头部签名
    local http_string="$method\n$uri\n\n"
    http_string="${http_string}content-type:$content_type\n"
    http_string="${http_string}host:$host\n"
    http_string="${http_string}\n"

    # 添加URL参数（这里为空）
    http_string="${http_string}\n"

    # 计算SHA256
    local http_string_sha256=$(echo -n "$http_string" | openssl dgst -sha256 | cut -d' ' -f2)

    # 构建签名字符串
    local string_to_sign="sha256\n$sign_time\n$header_list_lowercase\n$url_param_list_lowercase\n$http_string_sha256"

    # 计算签名密钥
    local secret_key=$(echo -n "$key_time" | openssl dgst -sha256 -hmac "$TENCENT_SECRET_KEY" -binary | xxd -p | tr '[:lower:]' '[:upper:]')
    local signature_key=$(echo -n "$secret_key" | openssl dgst -sha256 -hmac "$TENCENT_SECRET_KEY" -binary)

    # 计算最终签名
    local signature=$(echo -n "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$secret_key" -binary | base64)

    # 构建Authorization头
    local authorization="q-sign-algorithm=sha1&q-ak=$TENCENT_SECRET_ID&q-sign-time=$sign_time&q-key-time=$key_time&q-header-list=$header_list_lowercase&q-url-param-list=$url_param_list_lowercase&q-signature=$signature"

    local url="https://$host$uri"

    log_info "上传: $file_path -> $remote_path"
    log_info "URL: $url"

    # 添加调试信息
    log_info "调试信息:"
    log_info "  Host: $host"
    log_info "  Method: $method"
    log_info "  Content-Type: $content_type"
    log_info "  Key Time: $key_time"

    if curl -v -X PUT \
        -H "Content-Type: $content_type" \
        -H "Host: $host" \
        -H "Authorization: $authorization" \
        -H "x-cos-content-sha256: $http_string_sha256" \
        --upload-file "$file_path" \
        "$url" 2>&1; then
        log_info "✓ 上传成功"
        return 0
    else
        log_error "✗ 上传失败"
        return 1
    fi
}

# 阿里云OSS上传函数
upload_to_aliyun_oss() {
    local file_path="$1"
    local remote_path="$2"

    # 构建请求
    local method="PUT"
    local host="${ALIYUN_BUCKET}.oss-${ALIYUN_REGION}.aliyuncs.com"
    local uri="/$remote_path"
    local date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
    local content_type="application/octet-stream"

    # 计算签名
    local string_to_sign="$method\n\n$content_type\n$date\n$uri"
    local signature=$(echo -n "$string_to_sign" | openssl dgst -sha1 -hmac "$ALIYUN_ACCESS_KEY_SECRET" -binary | base64)
    local authorization="OSS ${ALIYUN_ACCESS_KEY_ID}:$signature"

    local url="https://$host$uri"

    log_info "上传: $file_path -> $remote_path"

    if curl -s -X PUT \
        -H "Date: $date" \
        -H "Authorization: $authorization" \
        -H "Content-Type: $content_type" \
        --upload-file "$file_path" \
        "$url"; then
        log_info "✓ 上传成功"
        return 0
    else
        log_error "✗ 上传失败"
        return 1
    fi
}

# 使用官方命令行工具上传
upload_with_official_tools() {
    local file_path="$1"
    local remote_path="$2"

    if [ "$CDN_TYPE" = "tencent" ]; then
        if command -v coscli >/dev/null 2>&1; then
            log_info "使用腾讯云COSCLI上传: $remote_path"
            if coscli upload "$file_path" "cos://${TENCENT_BUCKET}/$remote_path" \
                --region "$TENCENT_REGION" --part-size 10 >/dev/null 2>&1; then
                log_info "✓ 使用COSCLI上传成功"
                return 0
            else
                log_warn "COSCLI上传失败，尝试直接上传..."
            fi
        else
            log_warn "未找到COSCLI，建议先运行: ./install-coscli.sh"
        fi
    elif [ "$CDN_TYPE" = "aliyun" ]; then
        if command -v ossutil >/dev/null 2>&1; then
            log_info "使用阿里云ossutil上传: $remote_path"
            if ossutil cp "$file_path" "oss://$ALIYUN_BUCKET/$remote_path" \
                -i "$ALIYUN_ACCESS_KEY_ID" -k "$ALIYUN_ACCESS_KEY_SECRET" \
                --region "$ALIYUN_REGION" >/dev/null 2>&1; then
                log_info "✓ 使用ossutil上传成功"
                return 0
            else
                log_warn "ossutil上传失败，尝试直接上传..."
            fi
        else
            log_warn "未找到ossutil"
        fi
    fi

    return 1
}

# 批量上传函数
batch_upload() {
    log_info "使用批量上传模式..."

    if [ "$CDN_TYPE" = "tencent" ]; then
        if command -v coscli >/dev/null 2>&1; then
            local cos_url="cos://${TENCENT_BUCKET}/claude-mirror"
            log_info "上传到: $cos_url"
            log_info "本地目录: $SOURCE_DIR"

            if coscli sync "$SOURCE_DIR" "$cos_url" \
                --region "$TENCENT_REGION" \
                --delete \
                --part-size 10 \
                --thread-num 5; then
                log_info "✅ 批量上传成功"
                return 0
            else
                log_warn "批量上传失败，尝试逐个文件上传..."
                return 1
            fi
        else
            log_warn "未找到COSCLI，请先运行: ./install-coscli.sh"
            return 1
        fi
    elif [ "$CDN_TYPE" = "aliyun" ]; then
        if command -v ossutil >/dev/null 2>&1; then
            local oss_url="oss://$ALIYUN_BUCKET/claude-mirror"
            log_info "上传到: $oss_url"
            log_info "本地目录: $SOURCE_DIR"

            if ossutil cp -r "$SOURCE_DIR" "$oss_url" \
                --update \
                --parallel 5 \
                --bigfile-threshold 100000000; then
                log_info "✅ 批量上传成功"
                return 0
            else
                log_warn "批量上传失败，尝试逐个文件上传..."
                return 1
            fi
        else
            log_warn "未找到ossutil"
            return 1
        fi
    fi

    return 1
}

# 主上传函数
upload_files() {
    if [ ! -d "$SOURCE_DIR" ]; then
        log_error "源目录不存在: $SOURCE_DIR"
        log_info "请确保 ./claude-mirror 目录存在且包含要上传的文件"
        exit 1
    fi

    log_info "开始上传到 $CDN_TYPE CDN"
    log_info "源目录: $SOURCE_DIR"

    # 统计文件数量
    local total_files=$(find "$SOURCE_DIR" -type f | wc -l)
    local total_size=$(du -sh "$SOURCE_DIR" 2>/dev/null | cut -f1)

    log_info "文件数量: $total_files"
    log_info "总大小: $total_size"

    # 显示文件结构
    log_info "文件结构:"
    find "$SOURCE_DIR" -type f | sort | head -10
    if [ "$total_files" -gt 10 ]; then
        log_info "... 还有 $((total_files - 10)) 个文件"
    fi

    # 尝试批量上传
    if batch_upload; then
        local success_files=$total_files
    else
        # 批量上传失败，逐个文件上传
        log_info "切换到逐个文件上传模式..."
        local success_files=0

        # 遍历所有文件
        while IFS= read -r -d '' file_path; do
            # 计算相对路径
            local relative_path="${file_path#$SOURCE_DIR/}"

            # 移除开头的斜杠（如果有的话）
            relative_path="${relative_path#/}"

            if [ -z "$relative_path" ]; then
                continue
            fi

            log_info "上传: $relative_path"

            # 尝试上传
            if upload_with_official_tools "$file_path" "$relative_path"; then
                success_files=$((success_files + 1))
            else
                # 备用上传方法（保留原有逻辑）
                local upload_success=false

                if [ "$CDN_TYPE" = "tencent" ]; then
                    if upload_to_tencent_oss "$file_path" "$relative_path"; then
                        upload_success=true
                    fi
                elif [ "$CDN_TYPE" = "aliyun" ]; then
                    if upload_to_aliyun_oss "$file_path" "$relative_path"; then
                        upload_success=true
                    fi
                fi

                if [ "$upload_success" = true ]; then
                    success_files=$((success_files + 1))
                else
                    log_error "上传失败: $relative_path"
                fi
            fi

        done < <(find "$SOURCE_DIR" -type f -print0)
    fi

    echo ""
    log_info "上传完成！"
    log_info "总文件数: $total_files"
    log_info "成功上传: $success_files"
    log_info "失败文件: $((total_files - success_files))"

    if [ $success_files -eq $total_files ]; then
        log_info "✓ 所有文件上传成功！"

        # 生成CDN访问地址
        echo ""
        log_info "CDN访问地址:"
        if [ "$CDN_TYPE" = "tencent" ]; then
            echo "  https://${TENCENT_BUCKET}.cos.${TENCENT_REGION}.myqcloud.com/claude-mirror/"
        elif [ "$CDN_TYPE" = "aliyun" ]; then
            echo "  https://${ALIYUN_BUCKET}.oss-${ALIYUN_REGION}.aliyuncs.com/claude-mirror/"
        fi

        # 更新bootstrap.sh中的CDN地址
        update_bootstrap_script
    else
        log_error "部分文件上传失败，请检查"
        exit 1
    fi
}

# 更新bootstrap.sh中的CDN地址
update_bootstrap_script() {
    if [ ! -f "bootstrap.sh" ]; then
        log_warn "未找到bootstrap.sh文件，跳过更新"
        return
    fi

    local new_cdn_url=""
    if [ "$CDN_TYPE" = "tencent" ]; then
        new_cdn_url="https://${TENCENT_BUCKET}.cos.${TENCENT_REGION}.myqcloud.com/claude-mirror"
    elif [ "$CDN_TYPE" = "aliyun" ]; then
        new_cdn_url="https://${ALIYUN_BUCKET}.oss-${ALIYUN_REGION}.aliyuncs.com/claude-mirror"
    fi

    log_info "更新bootstrap.sh中的CDN地址..."

    # 更新第一个CDN源为新的地址
    sed -i.tmp "s|TENCENT_OSS_BASE=\"[^\"]*\"|TENCENT_OSS_BASE=\"$new_cdn_url\"|" bootstrap.sh
    rm -f bootstrap.sh.tmp

    log_info "✓ bootstrap.sh已更新"
}

# 主函数
main() {
    echo "======================================"
    echo "  CDN 上传脚本"
    echo "======================================"
    echo ""

    if [ -z "$CDN_TYPE" ]; then
        log_error "请指定CDN类型: --tencent 或 --aliyun"
        exit 1
    fi

    # 检查必要的配置
    if [ "$CDN_TYPE" = "tencent" ]; then
        if [ -z "$TENCENT_SECRET_ID" ] || [ -z "$TENCENT_SECRET_KEY" ] || \
           [ -z "$TENCENT_BUCKET" ] || [ -z "$TENCENT_REGION" ]; then
            log_error "腾讯云OSS配置不完整，请设置以下环境变量:"
            log_error "  TENCENT_SECRET_ID"
            log_error "  TENCENT_SECRET_KEY"
            log_error "  TENCENT_BUCKET"
            log_error "  TENCENT_REGION"
            exit 1
        fi
    elif [ "$CDN_TYPE" = "aliyun" ]; then
        if [ -z "$ALIYUN_ACCESS_KEY_ID" ] || [ -z "$ALIYUN_ACCESS_KEY_SECRET" ] || \
           [ -z "$ALIYUN_BUCKET" ] || [ -z "$ALIYUN_REGION" ]; then
            log_error "阿里云OSS配置不完整，请设置以下环境变量:"
            log_error "  ALIYUN_ACCESS_KEY_ID"
            log_error "  ALIYUN_ACCESS_KEY_SECRET"
            log_error "  ALIYUN_BUCKET"
            log_error "  ALIYUN_REGION"
            exit 1
        fi
    fi

    # 检查OpenSSL（用于签名）
    if ! command -v openssl >/dev/null 2>&1; then
        log_error "需要安装openssl用于签名计算"
        exit 1
    fi

    upload_files
}

# 运行主函数
main "$@"